package viewPackage;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Toolkit;

import javax.swing.JPanel;

import modelPackage.Player;
import modelPackage.WorldManager;
import modelPackage.WorldManagerInterface;

@SuppressWarnings("serial")
public class DrawingManager extends JPanel {

	private WorldManagerInterface WMan;
	private String PlayerID;
	static private int TILE_SIZE = 50; 
	
	public DrawingManager(WorldManager world, String ID, int x, int y) {
		super();
		WMan = world;
		PlayerID = ID;
		this.setBounds(0, 0, x, y);
	}
	
	@Override
	public void repaint() {
		super.repaint();
	}
	
	@Override
	public void paintComponent(Graphics g) {
		
		Graphics2D g2D = (Graphics2D) g;
		
		int TILE_SIZE = 50;
		
		Point backgroundScreen = mapToScreenBG(WMan.getPlayer(PlayerID));
		
		g2D.drawImage(WMan.getPlayer(PlayerID).getMap().getBackgroundImage(), backgroundScreen.x,backgroundScreen.y, null);
		
		int h = WMan.getPlayer(PlayerID).getMap().getHeight();
		int w = WMan.getPlayer(PlayerID).getMap().getWidth();
		
		//Draw all the tiles.
		if (WMan.getPlayer(PlayerID).getMap().getTiles().size() != 0) {
			for (int i = 0; i < h; i++) {
				for (int j = 0; j < w; j++) {
					Point mapLocation = new Point(j*TILE_SIZE, i*TILE_SIZE);
					Point screenLocation = mapToScreen(mapLocation);
					g2D.drawImage(WMan.getPlayer(PlayerID).getMap().getTiles().get(i*w + j).getImage(), screenLocation.x, screenLocation.y, null);
				}
			}
		}
		//If map smaller than screen, pad with black tiles.
		if (WMan.getPlayer(PlayerID).getMap().getHeight()*TILE_SIZE < this.getHeight()) {
			this.padScreenY(g2D);
		}
		if (WMan.getPlayer(PlayerID).getMap().getWidth()*TILE_SIZE < this.getWidth()) {
			this.padScreenX(g2D);
		}
			
		
		//Draw all the sprites.
		if (WMan.getPlayer(PlayerID).getMap().getSprites().size() != 0) {
			for (int i = 0; i < WMan.getPlayer(PlayerID).getMap().getSprites().size(); i++) {
				int x = WMan.getPlayer(PlayerID).getMap().getSprites().get(i).getPosition().x;
				int y = WMan.getPlayer(PlayerID).getMap().getSprites().get(i).getPosition().y;
				Point mapLocation = new Point(x,y);
				Point screenLocation = mapToScreen(mapLocation);
				g2D.drawImage(WMan.getPlayer(PlayerID).getMap().getSprites().get(i).getImage(), screenLocation.x, screenLocation.y, null);
			}
		}
		
		//Draw all the players.
		if (WMan.getPlayers().size() != 0) {
			for (int i = 0; i < WMan.getPlayers().size(); i++) {
				int x = WMan.getPlayers().get(i).getPosition().x;
				int y = WMan.getPlayers().get(i).getPosition().y;
				Point mapLocation = new Point(x,y);
				Point screenLocation = mapToScreen(mapLocation);
				g2D.drawImage(WMan.getPlayers().get(i).getImage(), screenLocation.x, screenLocation.y, null);
			}
		}
		
		//Draw current player lives.
		g2D.setColor(Color.WHITE);
		g2D.setFont(new Font("SansSerif", Font.BOLD, 20));
		g2D.drawString("Mans: " + Integer.toString(WMan.getPlayer(PlayerID).getRemainingLives()), 10, this.getHeight() - 30);
		g2D.setColor(Color.BLACK);
	}
	
	@Override
	public void setCursor(Cursor c) {
		super.setCursor(c);
	}
	
	public void padScreenY(Graphics2D g2d) {
		int screenY = this.getHeight();
		int mapPixelsHeight = WMan.getPlayer(PlayerID).getMap().getHeight()*TILE_SIZE;
		int d = (screenY - mapPixelsHeight) / 2;
		
		int numYTiles = d / TILE_SIZE;
		if (d % TILE_SIZE != 0) {
			numYTiles += 1;
		}
		
		int numXTiles = this.getWidth() / TILE_SIZE;
		if (this.getWidth() % TILE_SIZE != 0) {
			numXTiles +=1;
		}
		
		Point p1 = new Point(0, d - (numYTiles * TILE_SIZE));
		Point p2 = new Point(0, d + mapPixelsHeight);
		
		for (int y = 0; y < numYTiles; y++) {
			for (int x = 0; x < numXTiles; x++) {
				g2d.drawImage(Toolkit.getDefaultToolkit().getImage("images/Tiles/black.png"), p1.x + (x*TILE_SIZE), p1.y + (y*TILE_SIZE) , null);
				g2d.drawImage(Toolkit.getDefaultToolkit().getImage("images/Tiles/black.png"), p2.x + (x*TILE_SIZE), p2.y + (y*TILE_SIZE) , null);
			}
		}
		
	}
	
	public void padScreenX(Graphics2D g2d) {
		int screenX = this.getWidth();
		int mapPixelsWidth = WMan.getPlayer(PlayerID).getMap().getWidth()*TILE_SIZE;
		int d = (screenX - mapPixelsWidth) / 2;
		
		int numXTiles = d / TILE_SIZE;
		if (d % TILE_SIZE != 0) {
			numXTiles += 1;
		}
		
		int numYTiles = this.getHeight() / TILE_SIZE;
		if (this.getHeight() % TILE_SIZE != 0) {
			numYTiles +=1;
		}
		
		Point p1 = new Point(d - (numXTiles * TILE_SIZE), 0);
		Point p2 = new Point(d + mapPixelsWidth, 0);
		
		for (int y = 0; y < numYTiles; y++) {
			for (int x = 0; x < numXTiles; x++) {
				g2d.drawImage(Toolkit.getDefaultToolkit().getImage("images/Tiles/black.png"), p1.x + (x*TILE_SIZE), p1.y + (y*TILE_SIZE) , null);
				g2d.drawImage(Toolkit.getDefaultToolkit().getImage("images/Tiles/black.png"), p2.x + (x*TILE_SIZE), p2.y + (y*TILE_SIZE) , null);
			}
		}
	}
	
	public Point mapToScreenBG(Player p) {
		
		Point screenPoint = new Point(0,0);
		
		screenPoint = mapToScreen(screenPoint);
		
		int screenX = this.getWidth();
		
		int mapWidthPixels = p.getMap().getWidth()*TILE_SIZE;
		
		int backgroundWidth = p.getMap().getBackgroundImage().getWidth(null); 
		
		double factor = (double) (backgroundWidth - screenX) / (double) mapWidthPixels;
	
		screenPoint.x *= factor;
		
		return screenPoint;
		
	}



	public Point mapToScreen(Point mapPoint) {
		
		Point screenPoint = mapPoint;
		
		int screenX = this.getWidth();
		int screenY = this.getHeight();
		
		int mapTilesHeight = WMan.getPlayer(PlayerID).getMap().getHeight();
		int mapPixelsHeight = mapTilesHeight*TILE_SIZE;
		
		int mapTilesWidth = WMan.getPlayer(PlayerID).getMap().getWidth();
		int mapPixelsWidth = mapTilesWidth*TILE_SIZE;
		
		int xMinLimit = screenX / 4;
		int xMaxLimit = 3 * xMinLimit;
		
		int xLimit = screenX / 2;
		
		xMinLimit = xLimit;
		xMaxLimit = xLimit;
		
		int yTopLimit = screenY / 4;
		int yBottomLimit = 3 * yTopLimit;
		
		
		//Handle the Y direction.
		if (mapPixelsHeight == screenY) {
			//Let it be.
		}
		else if (mapPixelsHeight < screenY) {
			//Center it.
			int d = (screenY - mapPixelsHeight) / 2;
			screenPoint.y = mapPoint.y + d;			
		}
		else if (mapPixelsHeight > screenY) {
			//Show only part of it.
			
			
			/*
			 * HERE IS WHERE THE UP/DOWN SCROLLING WILL GO.
			 * 
			 * */
			
			
		}
		
		
		//Handle the X direction.
		if (mapPixelsWidth == screenX) {
			//Let it be.
		}
		else if (mapPixelsWidth < screenX) {
			//Center it.
			int d = (screenX - mapPixelsWidth) / 2;
			screenPoint.x = mapPoint.x + d;
		}
		else if (mapPixelsWidth > screenX) {
			//Show only part of it.
			
			//if (WMan.getPlayer(PlayerID).getPosXVelocity()) {
				//If you're close enough to the left wall, do nothing, no adjustment.
				if (WMan.getPlayer(PlayerID).getPosition().x + WMan.getPlayer(PlayerID).getWidth() <= xMaxLimit) {
					//Do nothing!
				}
			
				//If you're close enough to the right wall, keep that wall at the edge.
				else if (WMan.getPlayer(PlayerID).getPosition().x + WMan.getPlayer(PlayerID).getWidth() >= (mapPixelsWidth - xMinLimit)) {
					screenPoint.x = mapPoint.x - (mapPixelsWidth - screenX);
				}
			
				//If you reach 3/4 of the screen, scroll the screen.
				else if (WMan.getPlayer(PlayerID).getPosition().x + WMan.getPlayer(PlayerID).getWidth() > xMaxLimit) {
					screenPoint.x = mapPoint.x + (xMaxLimit - (WMan.getPlayer(PlayerID).getPosition().x + WMan.getPlayer(PlayerID).getWidth()));
				}
				
				/*
				 *                                    ||
				 * I'D REALLY LIKE TO MAKE THIS WORK. \/ 
				 * 
				 * */
				
				
				
			//}
			/*
			else if (WMan.getPlayer(PlayerID).getNegXVelocity()) {
				//If you're close enough to the right wall, do nothing, no adjustment, keep that wall at the edge.
				if (WMan.getPlayer(PlayerID).getPosition().x >= mapPixelsWidth - xMaxLimit) {
					screenPoint.x = mapPoint.x - (mapPixelsWidth - screenX);
				}
			
				//If you're close enough to the left wall, do nothing.
				else if (WMan.getPlayer(PlayerID).getPosition().x <= xMinLimit) {
					//Do nothing.
				}
			
				//If you reach 1/4 of the screen, scroll the screen.
				else if (WMan.getPlayer(PlayerID).getPosition().x < mapPixelsWidth - xMaxLimit) {
					screenPoint.x = mapPoint.x + (xMaxLimit - (WMan.getPlayer(PlayerID).getPosition().x + WMan.getPlayer(PlayerID).getWidth()));
				}
			}
			*/
			
		}
		
		
		return screenPoint;
	}
	
	public Point screenToMap(Point screenPoint) {
		//Eventually this will convert.
		Point mapPoint = screenPoint;
		
		return mapPoint;
	}
	
}